<template>
  <div class="picture-list">
    <!-- 图片列表 -->
    <div class="picture-grid" :class="{ 'with-animation': enableAnimation }">
      <div
        v-for="(picture, index) in dataList"
        :key="picture.id"
        class="picture-item"
        :style="enableAnimation ? { '--index': index } : {}"
      >
        <a-card hoverable @click="doClickPicture(picture)" class="picture-card">
          <template #cover>
            <div class="image-wrapper">
              <img
                :alt="picture.name"
                :src="picture.thumbnailUrl ?? picture.url"
                :data-picture-id="picture.id"
                class="picture-image"
                :class="{ loaded: imageLoadedMap[picture.id] }"
                @load="onImageLoad"
              />
              <transition name="fade">
                <div class="image-placeholder" v-if="!imageLoadedMap[picture.id]">
                  <a-spin />
                </div>
              </transition>
            </div>
          </template>
          <a-card-meta :title="picture.name">
            <template #description>
              <a-flex>
                <a-tag color="green">
                  {{ picture.category ?? '默认' }}
                </a-tag>
                <a-tag v-for="tag in picture.tags" :key="tag">
                  {{ tag }}
                </a-tag>
              </a-flex>
            </template>
          </a-card-meta>
          <template v-if="showOp" #actions>
            <a-space @click="(e) => doEdit(picture, e)">
              <EditOutlined />
              编辑
            </a-space>
            <a-space @click="(e) => doDelete(picture, e)">
              <DeleteOutlined />
              删除
            </a-space>
          </template>
        </a-card>
      </div>
    </div>
    <!-- 加载状态 -->
    <div v-if="loading" class="loading-wrapper">
      <a-spin size="large" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue'
import { deletePictureUsingPost } from '@/api/pictureController.ts'
import { message } from 'ant-design-vue'

interface Props {
  dataList?: API.PictureVO[]
  loading?: boolean
  showOp?: boolean
  onReload?: () => void
  enableAnimation?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  dataList: () => [],
  loading: false,
  showOp: false,
  enableAnimation: false,
})

const router = useRouter()
// 图片加载状态映射
const imageLoadedMap = ref<Record<string, boolean>>({})

// 图片加载完成
const onImageLoad = (event: Event) => {
  const img = event.target as HTMLImageElement
  const pictureId = img.getAttribute('data-picture-id')
  if (pictureId) {
    imageLoadedMap.value[pictureId] = true
  }
}

// 监听数据列表变化，检查已缓存的图片
watch(() => props.dataList, (newList) => {
  if (newList) {
    imageLoadedMap.value = {}
    newList.forEach((picture) => {
      const imageUrl = picture.thumbnailUrl ?? picture.url
      if (imageUrl) {
        const img = new Image()
        img.src = imageUrl
        if (img.complete) {
          imageLoadedMap.value[picture.id] = true
        } else {
          imageLoadedMap.value[picture.id] = false
          img.onload = () => {
            imageLoadedMap.value[picture.id] = true
          }
        }
      }
    })
  }
}, { immediate: true })
// 跳转至图片详情页
const doClickPicture = (picture: API.PictureVO) => {
  router.push({
    path: `/picture/${picture.id}`,
  })
}

// 编辑
const doEdit = (picture, e) => {
  // 阻止冒泡
  e.stopPropagation()
  // 跳转时一定要携带 spaceId
  router.push({
    path: '/add_picture',
    query: {
      id: picture.id,
      spaceId: picture.spaceId,
    },
  })
}

// 删除数据
const doDelete = async (picture, e) => {
  // 阻止冒泡
  e.stopPropagation()
  const id = picture.id
  if (!id) {
    return
  }
  const res = await deletePictureUsingPost({ id })
  if (res.data.code === 0) {
    message.success('删除成功')
    props.onReload?.()
  } else {
    message.error('删除失败')
  }
}
</script>

<style scoped>
.picture-list {
  position: relative;
  min-height: 200px;
}

.picture-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

@media (max-width: 576px) {
  .picture-grid {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 576px) and (max-width: 768px) {
  .picture-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 768px) and (max-width: 992px) {
  .picture-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 992px) and (max-width: 1200px) {
  .picture-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (min-width: 1200px) and (max-width: 1600px) {
  .picture-grid {
    grid-template-columns: repeat(5, 1fr);
  }
}

@media (min-width: 1600px) {
  .picture-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

/* 淡入淡出动画 - 只在启用动画时生效 */
.picture-grid.with-animation .picture-item {
  animation: fadeInUp 0.6s ease-out forwards;
  opacity: 0;
  animation-delay: calc(var(--index) * 0.08s);
}

/* 不启用动画时直接显示 */
.picture-grid:not(.with-animation) .picture-item {
  opacity: 1;
  animation: none;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 卡片样式 */
.picture-card {
  height: 100%;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.picture-card:hover {
  transform: translateY(-8px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

/* 图片容器 */
.image-wrapper {
  position: relative;
  width: 100%;
  height: 180px;
  overflow: hidden;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}

.picture-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.6s ease, transform 0.3s ease;
  opacity: 0;
  transform: scale(1);
}

.picture-image.loaded {
  opacity: 1;
}

.picture-card:hover .picture-image {
  transform: scale(1.08);
}

/* 图片加载占位符 */
.image-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading 1.5s ease-in-out infinite;
  transition: opacity 0.3s ease;
}

/* 占位符淡出动画 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@keyframes loading {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

/* 加载状态 */
.loading-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px 0;
}
</style>

